#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <termios.h>

#define SERIAL_PORT "/dev/ttyS0"
#define SOCKET_PORT 12345
#define BUFFER_SIZE 1024

int main() {
    int sockfd, serialfd;
    struct sockaddr_in serv_addr;
    char buffer[BUFFER_SIZE];

    // Create socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("Error creating socket");
        exit(EXIT_FAILURE);
    }

    // Setup server address
    memset(&serv_addr, '0', sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(SOCKET_PORT);

    // Convert IP address to binary form
    if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
        perror("Invalid address/Address not supported");
        exit(EXIT_FAILURE);
    }

    // Connect to server
    if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        perror("Connection failed");
        exit(EXIT_FAILURE);
    }

    // Open serial port
    serialfd = open(SERIAL_PORT, O_RDWR);
    if (serialfd < 0) {
        perror("Error opening serial port");
        exit(EXIT_FAILURE);
    }

    // Configure serial port settings (baud rate, etc.)
    struct termios options;
    tcgetattr(serialfd, &options);
    cfsetispeed(&options, B9600);
    cfsetospeed(&options, B9600);
    options.c_cflag |= (CLOCAL | CREAD);
    tcsetattr(serialfd, TCSANOW, &options);

    // Transfer data between socket and serial port
    while (1) {
        // Read from socket
        ssize_t n = read(sockfd, buffer, sizeof(buffer));
        if (n < 0) {
            perror("Error reading from socket");
            break;
        }

        // Write to serial port
        ssize_t written = write(serialfd, buffer, n);
        if (written < 0) {
            perror("Error writing to serial port");
            break;
        }

        // Read from serial port
        n = read(serialfd, buffer, sizeof(buffer));
        if (n < 0) {
            perror("Error reading from serial port");
            break;
        }

        // Write to socket
        written = write(sockfd, buffer, n);
        if (written < 0) {
            perror("Error writing to socket");
            break;
        }
    }

    // Close sockets and serial port
    close(sockfd);
    close(serialfd);

    return 0;
}

